Package org.python.pydev.builder.pep8

Source Code of org.python.pydev.builder.pep8.Pep8Visitor

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.builder.pep8;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.python.core.Py;
import org.python.core.PyObject;
import org.python.pydev.core.NullOutputStream;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.codecompletion.revisited.modules.SourceModule;
import org.python.pydev.jython.IPythonInterpreter;
import org.python.pydev.jython.JythonPlugin;

import com.aptana.shared_core.string.FastStringBuffer;
import com.python.pydev.analysis.IAnalysisPreferences;
import com.python.pydev.analysis.messages.IMessage;
import com.python.pydev.analysis.messages.Message;
import com.python.pydev.analysis.ui.AnalysisPreferencesPage;

/**
* @author Fabio
*
*/
public class Pep8Visitor {

    private static final String EXECUTE_PEP8 = "import sys\n"
            + "argv = ['pep8.py', r'%s'%s]\n"
            + "sys.argv=argv\n"
            + //It always accesses sys.argv[0] in process_options, so, it must be set.
            "\n"
            + "if pep8 == None:\n"
            + //Optimization: if possible don't import pep8 (the import was the slowest thing in this code).
            "    add_to_pythonpath = '%s'\n"
            + "    if add_to_pythonpath not in sys.path:\n"
            + "        sys.path.append(add_to_pythonpath)\n"
            + "    import pep8\n"
            + "\n"
            + "options, args = pep8.process_options(argv[1:])\n"
            + //don't use sys.argv (it seems it doesn't get updated as it should).
              //"print options\n" + uncomment for debugging options
            "checker = pep8.Checker(options, '%s', lines)\n" +
            "\n"
            + "def report_error(line_number, offset, text, check):\n" +
            "    code = text[:4]\n"
            + "    if pep8.ignore_code(checker.options, code) or code in checker.expected:\n" +
            "        return\n"
            + "    visitor.reportError(line_number, offset, text, check)\n"
            + "    return original(line_number, offset, text, check)\n" +
            "\n" +
            "\n"
            + "original = checker.report_error\n" +
            "checker.report_error = report_error\n" +
            "\n"
            + "checker.check_all()\n" +
            "\n" +
            "";

    private final List<IMessage> messages = new ArrayList<IMessage>();
    private IAnalysisPreferences prefs;
    private IDocument document;
    private volatile static PyObject pep8;
    private static final Object lock = new Object();
    private String messageToIgnore;

    public List<IMessage> getMessages(SourceModule module, IDocument document, IProgressMonitor monitor,
            IAnalysisPreferences prefs) {
        try {

            if (prefs.getSeverityForType(IAnalysisPreferences.TYPE_PEP8) < IMarker.SEVERITY_WARNING) {
                return messages;
            }
            messageToIgnore = prefs.getRequiredMessageToIgnore(IAnalysisPreferences.TYPE_PEP8);

            String[] pep8CommandLine = AnalysisPreferencesPage.getPep8CommandLine();

            FastStringBuffer args = new FastStringBuffer(pep8CommandLine.length * 20);
            for (String string : pep8CommandLine) {
                args.append(',').append("r'").append(string).append('\'');
            }

            String pep8Location = AnalysisPreferencesPage.getPep8Location();

            File pep8Loc = new File(pep8Location);

            if (!pep8Loc.exists()) {
                Log.log("Specified location for pep8.py does not exist (" + pep8Location + ").");
                return messages;
            }

            this.prefs = prefs;
            this.document = document;

            //It's important that the interpreter is created in the Thread and not outside the thread (otherwise
            //it may be that the output ends up being shared, which is not what we want.)
            boolean useConsole = AnalysisPreferencesPage.useConsole();
            IPythonInterpreter interpreter = JythonPlugin.newPythonInterpreter(useConsole, false);
            if (!useConsole) {
                interpreter.setErr(NullOutputStream.singleton);
                interpreter.setOut(NullOutputStream.singleton);
            }
            String file = StringUtils.replaceAllSlashes(module.getFile().getAbsolutePath());
            interpreter.set("visitor", this);

            List<String> splitInLines = StringUtils.splitInLines(document.get());
            interpreter.set("lines", splitInLines);
            PyObject tempPep8 = pep8;
            if (tempPep8 != null) {
                interpreter.set("pep8", tempPep8);
            } else {
                interpreter.set("pep8", Py.None);
            }

            String formatted = com.aptana.shared_core.string.StringUtils.format(EXECUTE_PEP8, file, args.toString(),
                    StringUtils.replaceAllSlashes(pep8Loc.getParentFile().getAbsolutePath()), //put the parent dir of pep8.py in the pythonpath.
                    file);
            interpreter.exec(formatted);
            if (pep8 == null) {
                synchronized (lock) {
                    if (pep8 == null) {
                        pep8 = interpreter.get("pep8");
                    }
                }
            }

        } catch (Exception e) {
            Log.log("Error analyzing: " + module, e);
        }

        return messages;
    }

    /**
     *
     */
    public void reportError(int lineNumber, int offset, String text, Object check) {
        int len;
        try {
            len = this.document.getLineLength(lineNumber - 1);
        } catch (BadLocationException e) {
            return; // the document changed in the meanwhile...
        }
        if (messageToIgnore != null) {
            int startLine = lineNumber - 1;
            String line = PySelection.getLine(document, startLine);
            if (line.indexOf(messageToIgnore) != -1) {
                //keep going... nothing to see here...
                return;
            }
        }

        messages.add(new Message(IAnalysisPreferences.TYPE_PEP8, text, lineNumber, lineNumber, offset + 1, len, prefs));
    }

}
TOP

Related Classes of org.python.pydev.builder.pep8.Pep8Visitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.